package com.example.lib_data.utils

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**倒计时封装
 * 1. 倒数 正数
 * 2. 随时暂停
 * 3. 暂停 -> 启动
 * 4. 回调当前数的数字
 * 5. 自己设置间隔时间
 *
 * 自定义类内部顺序：私有属性  公开的属性   public方法  private方法  内部类
 *
 *  建造者模式
 * PXDTimer().timeInterver(1000).order(Order.DOWN).callback({ num}).build().start()
 */
class PXDTimer {
    private var mInterval = 1000L // 时间间隔
    private var mOrder = Order.DOWN //升序还是降序
    private var mCallBack:(PXDTimer,Int)->Unit = {_, _ ->  } //回调
    private var mOriginalValue = 0 //初始值
    private var job:Job? = null //计数的任务对象

    /**
     * 设置时间间隔
     */
    fun timeInterval(interval: Long): PXDTimer {
        mInterval = interval
        return this
    }

    /**
     * 设置顺序 升序还是降序
     */
    fun order(order:Order):PXDTimer{
        mOrder = order
        return this
    }

    /**
     * 回调数据
     * */
    fun setCallback(callback:(PXDTimer,Int)->Unit):PXDTimer{
        mCallBack = callback
        return this
    }

    /**
     * 设置初始值
     */
    fun startValue(value:Int):PXDTimer{
        mOriginalValue = value
        return this
    }

    /**
     * 开启定时
     */
    fun start(){
        job = CoroutineScope(Dispatchers.IO).launch {
            while (isActive){
                delay(mInterval)
                if (mOrder != Order.NONE) { //需要计数
                    if (mOrder == Order.DOWN) mOriginalValue-- else mOriginalValue++
                }
                //回调数据
                withContext(Dispatchers.Main){
                    mCallBack(this@PXDTimer ,mOriginalValue)
                }
            }
        }
    }

    /**
     * 暂停定时
     */
    fun stop(){
        job?.let {
            CoroutineScope(Dispatchers.Main).launch {
                it.cancelAndJoin()
            }
        }
    }

    /**正数还是倒数*/
    enum class Order {
        DOWN, UP, NONE
    }
}